Import Library & data¶
In [9]:
import SPIX
import scanpy as sc
import squidpy as sq
import matplotlib.pyplot as plt
/home/Data_Drive_8TB/chs1151/.conda/envs/V_t/lib/python3.10/site-packages/tqdm_joblib/__init__.py:4: TqdmExperimentalWarning: Using `tqdm.autonotebook.tqdm` in notebook mode. Use `tqdm.tqdm` instead to force console mode (e.g. in jupyter console) from tqdm.autonotebook import tqdm
In [10]:
# adata = sc.read_h5ad('/path/to/your/dir/Anndata.h5ad')
# adata = sq.datasets.slideseqv2()
### Use raw counts if you can use
# adata.X = adata.layers['count'].copy()
### Cal Original MoranI
# sc.pp.filter_genes(adata, min_cells=1)
# sc.pp.normalize_total(adata)
# sc.pp.log1p(adata)
# sq.gr.spatial_neighbors(adata)
# sq.gr.spatial_autocorr(adata, mode="moran", genes=adata.var_names)
# adata.uns["moranI"][adata.uns["moranI"]['I']>0.1].head()
# original_moranI = adata.uns["moranI"][adata.uns["moranI"]['I']>0.1].copy()
### Use raw counts if you can use
# adata.X = adata.layers['count'].copy()
In [11]:
adata
Out[11]:
AnnData object with n_obs × n_vars = 41786 × 17733
obs: 'barcode', 'x', 'y', 'n_genes_by_counts', 'log1p_n_genes_by_counts', 'total_counts', 'log1p_total_counts', 'pct_counts_in_top_50_genes', 'pct_counts_in_top_100_genes', 'pct_counts_in_top_200_genes', 'pct_counts_in_top_500_genes', 'total_counts_MT', 'log1p_total_counts_MT', 'pct_counts_MT', 'n_counts', 'leiden', 'cluster'
var: 'MT', 'n_cells_by_counts', 'mean_counts', 'log1p_mean_counts', 'pct_dropout_by_counts', 'total_counts', 'log1p_total_counts', 'n_cells', 'highly_variable', 'highly_variable_rank', 'means', 'variances', 'variances_norm'
uns: 'cluster_colors', 'hvg', 'leiden', 'leiden_colors', 'neighbors', 'pca', 'spatial_neighbors', 'umap', 'moranI'
obsm: 'X_pca', 'X_umap', 'deconvolution_results', 'spatial'
obsp: 'connectivities', 'distances', 'spatial_connectivities', 'spatial_distances'
Generate Embeddings & Tiles¶
In [12]:
adata = SPIX.tm.generate_embeddings(
adata,
dim_reduction='PCA',
normalization='none', # already normalized data
dimensions=30,
nfeatures=2000,
n_jobs=16,
filter_grid=1,
filter_threshold=0.995,
tensor_resolution=1,
chunksize=3000,
verbose=True
)
2025-04-09 03:40:43,545 - INFO - Starting generate_embeddings... 2025-04-09 03:40:43,546 - INFO - Tiles not found. Generating tiles... 2025-04-09 03:40:43,546 - INFO - Starting generate_tiles... 2025-04-09 03:40:43,549 - INFO - Original coordinates: (41786, 2) 2025-04-09 03:40:43,550 - INFO - Performing Voronoi tessellation... 2025-04-09 03:40:43,939 - INFO - Voronoi tessellation completed. 2025-04-09 03:40:43,940 - INFO - Filtering tiles... Calculating Voronoi region areas: 100%|██████████| 41786/41786 [00:01<00:00, 20974.54it/s] Filtering tiles by area: 100%|██████████| 41738/41738 [00:00<00:00, 2755491.10it/s] 2025-04-09 03:40:45,963 - INFO - Filtered regions: 41529, Filtered coordinates: (41529, 2) 2025-04-09 03:40:45,964 - INFO - Rasterising tiles... Rasterising tiles: 100%|██████████| 41529/41529 [00:08<00:00, 4939.68it/s] 2025-04-09 03:40:58,265 - INFO - Rasterisation completed. Number of tiles: 18401456 2025-04-09 03:40:58,266 - INFO - Tiles have been stored in adata.uns['tiles']. 2025-04-09 03:40:59,372 - INFO - adata has been subset from 41786 to 41529 observations based on filtered tiles. 2025-04-09 03:40:59,373 - INFO - generate_tiles completed. 2025-04-09 03:40:59,388 - INFO - Processing counts... 2025-04-09 03:40:59,389 - INFO - Processing counts with method: none 2025-04-09 03:40:59,616 - INFO - Counts processing completed. 2025-04-09 03:40:59,642 - INFO - Embedding latent space... 2025-04-09 03:40:59,643 - INFO - Embedding latent space using PCA... 2025-04-09 03:41:00,599 - INFO - Latent space embedding completed. 2025-04-09 03:41:00,601 - INFO - generate_embeddings completed.
In [13]:
SPIX.pl.image_plot(
adata,
dimensions=[0, 1, 2],
embedding='X_embedding',
figsize=(10, 10), # Adjust figure size here
scaling_factor=10, # Adjust point size here
origin=True
)
Image Processing¶
Smooth Image¶
In [14]:
SPIX.ip.smooth_image(
adata,
dimensions = list(range(30)),
sigma=10,
n_jobs=30,
multi_method='loky'
)
2025-04-09 03:41:00,928 - INFO - Starting smooth_image... 2025-04-09 03:41:00,933 - INFO - Using embedding 'X_embedding' with shape (41529, 30). 2025-04-09 03:41:01,146 - INFO - Shifting coordinates by (-691, -468) to start from 0. 2025-04-09 03:41:01,565 - INFO - Image size: width=5294, height=5258 2025-04-09 03:41:01,566 - INFO - Starting parallel processing of dimensions... Filling NaNs: 0%| | 0/30 [00:00<?, ?it/s]
0%| | 0/30 [00:00<?, ?it/s]
2025-04-09 03:41:16,057 - INFO - Filling NaNs for dimension 0... 2025-04-09 03:41:17,016 - INFO - Filling NaNs for dimension 1... 2025-04-09 03:41:18,052 - INFO - Filling NaNs for dimension 2... 2025-04-09 03:41:18,410 - INFO - Filling NaNs for dimension 3... 2025-04-09 03:41:19,266 - INFO - Filling NaNs for dimension 4... 2025-04-09 03:41:20,313 - INFO - Filling NaNs for dimension 5... 2025-04-09 03:41:20,916 - INFO - Filling NaNs for dimension 6... 2025-04-09 03:41:22,112 - INFO - Filling NaNs for dimension 7... 2025-04-09 03:41:22,691 - INFO - Filling NaNs for dimension 8... 2025-04-09 03:41:24,143 - INFO - Filling NaNs for dimension 9... 2025-04-09 03:41:24,743 - INFO - Filling NaNs for dimension 10... 2025-04-09 03:41:25,471 - INFO - Filling NaNs for dimension 11... 2025-04-09 03:41:26,394 - INFO - Filling NaNs for dimension 12... 2025-04-09 03:41:26,892 - INFO - Filling NaNs for dimension 13... 2025-04-09 03:41:28,026 - INFO - Filling NaNs for dimension 14... 2025-04-09 03:41:28,657 - INFO - Filling NaNs for dimension 15... 2025-04-09 03:41:30,132 - INFO - Filling NaNs for dimension 17... 2025-04-09 03:41:30,517 - INFO - Filling NaNs for dimension 16... 2025-04-09 03:41:31,213 - INFO - Filling NaNs for dimension 18... 2025-04-09 03:41:32,499 - INFO - Filling NaNs for dimension 19... 2025-04-09 03:41:33,132 - INFO - Filling NaNs for dimension 20... 2025-04-09 03:41:33,787 - INFO - Filling NaNs for dimension 21... 2025-04-09 03:41:34,803 - INFO - Filling NaNs for dimension 22... 2025-04-09 03:41:35,182 - INFO - Filling NaNs for dimension 23... 2025-04-09 03:41:36,166 - INFO - Filling NaNs for dimension 24... 2025-04-09 03:41:36,991 - INFO - Filling NaNs for dimension 25... 2025-04-09 03:41:38,269 - INFO - Filling NaNs for dimension 26... 2025-04-09 03:41:39,094 - INFO - Filling NaNs for dimension 27... 2025-04-09 03:41:39,557 - INFO - Filling NaNs for dimension 28... 2025-04-09 03:41:40,267 - INFO - Filling NaNs for dimension 29... Filling NaNs: 0%| | 0/30 [00:45<?, ?it/s] Smoothing dimensions: 0%| | 0/30 [00:00<?, ?it/s]
0%| | 0/30 [00:00<?, ?it/s]
2025-04-09 03:41:48,735 - INFO - Smoothing for dimension 0... 2025-04-09 03:41:48,797 - INFO - Iteration 1/1 for dimension 0. 2025-04-09 03:41:49,543 - INFO - Smoothing for dimension 1... 2025-04-09 03:41:49,599 - INFO - Iteration 1/1 for dimension 1. 2025-04-09 03:41:50,394 - INFO - Smoothing for dimension 2... 2025-04-09 03:41:50,452 - INFO - Iteration 1/1 for dimension 2. 2025-04-09 03:41:51,207 - INFO - Smoothing for dimension 3... 2025-04-09 03:41:51,351 - INFO - Iteration 1/1 for dimension 3. 2025-04-09 03:41:52,245 - INFO - Smoothing for dimension 4... 2025-04-09 03:41:52,329 - INFO - Iteration 1/1 for dimension 4. 2025-04-09 03:41:53,463 - INFO - Smoothing for dimension 5... 2025-04-09 03:41:53,525 - INFO - Iteration 1/1 for dimension 5. 2025-04-09 03:41:54,774 - INFO - Smoothing for dimension 6... 2025-04-09 03:41:54,901 - INFO - Iteration 1/1 for dimension 6. 2025-04-09 03:41:55,840 - INFO - Smoothing for dimension 7... 2025-04-09 03:41:55,982 - INFO - Iteration 1/1 for dimension 7. 2025-04-09 03:41:56,882 - INFO - Smoothing for dimension 8... 2025-04-09 03:41:56,947 - INFO - Iteration 1/1 for dimension 8. 2025-04-09 03:41:57,965 - INFO - Smoothing for dimension 9... 2025-04-09 03:41:58,027 - INFO - Iteration 1/1 for dimension 9. 2025-04-09 03:41:59,137 - INFO - Smoothing for dimension 10... 2025-04-09 03:41:59,272 - INFO - Iteration 1/1 for dimension 10. 2025-04-09 03:42:00,138 - INFO - Smoothing for dimension 11... 2025-04-09 03:42:00,195 - INFO - Iteration 1/1 for dimension 11. 2025-04-09 03:42:01,191 - INFO - Smoothing for dimension 12... 2025-04-09 03:42:01,294 - INFO - Iteration 1/1 for dimension 12. 2025-04-09 03:42:02,200 - INFO - Smoothing for dimension 13... 2025-04-09 03:42:02,261 - INFO - Iteration 1/1 for dimension 13. 2025-04-09 03:42:03,219 - INFO - Smoothing for dimension 14... 2025-04-09 03:42:03,298 - INFO - Iteration 1/1 for dimension 14. 2025-04-09 03:42:04,249 - INFO - Smoothing for dimension 15... 2025-04-09 03:42:04,337 - INFO - Iteration 1/1 for dimension 15. 2025-04-09 03:42:05,381 - INFO - Smoothing for dimension 16... 2025-04-09 03:42:05,442 - INFO - Iteration 1/1 for dimension 16. 2025-04-09 03:42:06,361 - INFO - Smoothing for dimension 17... 2025-04-09 03:42:06,447 - INFO - Iteration 1/1 for dimension 17. 2025-04-09 03:42:07,433 - INFO - Smoothing for dimension 18... 2025-04-09 03:42:07,512 - INFO - Iteration 1/1 for dimension 18. 2025-04-09 03:42:08,512 - INFO - Smoothing for dimension 19... 2025-04-09 03:42:08,608 - INFO - Iteration 1/1 for dimension 19. 2025-04-09 03:42:09,615 - INFO - Smoothing for dimension 20... 2025-04-09 03:42:09,673 - INFO - Iteration 1/1 for dimension 20. 2025-04-09 03:42:10,602 - INFO - Smoothing for dimension 21... 2025-04-09 03:42:10,712 - INFO - Iteration 1/1 for dimension 21. 2025-04-09 03:42:11,656 - INFO - Smoothing for dimension 22... 2025-04-09 03:42:11,715 - INFO - Iteration 1/1 for dimension 22. 2025-04-09 03:42:13,655 - INFO - Smoothing for dimension 23... 2025-04-09 03:42:13,728 - INFO - Iteration 1/1 for dimension 23. 2025-04-09 03:42:14,899 - INFO - Smoothing for dimension 24... 2025-04-09 03:42:14,959 - INFO - Iteration 1/1 for dimension 24. 2025-04-09 03:42:15,801 - INFO - Smoothing for dimension 25... 2025-04-09 03:42:15,859 - INFO - Iteration 1/1 for dimension 25. 2025-04-09 03:42:16,783 - INFO - Smoothing for dimension 26... 2025-04-09 03:42:16,923 - INFO - Iteration 1/1 for dimension 26. 2025-04-09 03:42:17,745 - INFO - Smoothing for dimension 27... 2025-04-09 03:42:17,883 - INFO - Iteration 1/1 for dimension 27. 2025-04-09 03:42:18,774 - INFO - Smoothing for dimension 28... 2025-04-09 03:42:18,845 - INFO - Iteration 1/1 for dimension 28. 2025-04-09 03:42:19,588 - INFO - Smoothing for dimension 29... 2025-04-09 03:42:19,646 - INFO - Iteration 1/1 for dimension 29. Smoothing dimensions: 0%| | 0/30 [00:36<?, ?it/s] 2025-04-09 03:42:24,100 - INFO - Applying Min-Max scaling to the smoothed embeddings. 2025-04-09 03:42:24,112 - INFO - Smoothed embeddings stored in adata.obsm['X_embedding_smooth']. 2025-04-09 03:42:24,113 - INFO - Smoothing completed and embeddings updated in AnnData object.
Out[14]:
AnnData object with n_obs × n_vars = 41529 × 17733
obs: 'barcode', 'x', 'y', 'n_genes_by_counts', 'log1p_n_genes_by_counts', 'total_counts', 'log1p_total_counts', 'pct_counts_in_top_50_genes', 'pct_counts_in_top_100_genes', 'pct_counts_in_top_200_genes', 'pct_counts_in_top_500_genes', 'total_counts_MT', 'log1p_total_counts_MT', 'pct_counts_MT', 'n_counts', 'leiden', 'cluster'
var: 'MT', 'n_cells_by_counts', 'mean_counts', 'log1p_mean_counts', 'pct_dropout_by_counts', 'total_counts', 'log1p_total_counts', 'n_cells', 'highly_variable', 'highly_variable_rank', 'means', 'variances', 'variances_norm'
uns: 'cluster_colors', 'hvg', 'leiden', 'leiden_colors', 'neighbors', 'pca', 'spatial_neighbors', 'umap', 'moranI', 'tiles', 'tiles_generated', 'embedding_method', 'tensor_resolution', 'na_filled_images_dict', 'smoothed_images_dict'
obsm: 'X_pca', 'X_umap', 'deconvolution_results', 'spatial', 'X_embedding', 'X_embedding_smooth'
layers: 'log_norm'
obsp: 'connectivities', 'distances', 'spatial_connectivities', 'spatial_distances'
In [15]:
SPIX.pl.image_plot(
adata,
dimensions=[0, 1, 2],
embedding='X_embedding_smooth',
figsize=(10, 10), # Adjust figure size here
scaling_factor=10, # Adjust point size here
origin=True
)
Equalize Image¶
In [16]:
SPIX.ip.equalize_image(
adata,
dimensions=list(range(30)),
embedding='X_embedding_smooth',
sleft=5,sright=5)
Starting equalization... Equalizing dimension 0 using method 'BalanceSimplest' Equalizing dimension 1 using method 'BalanceSimplest' Equalizing dimension 2 using method 'BalanceSimplest' Equalizing dimension 3 using method 'BalanceSimplest' Equalizing dimension 4 using method 'BalanceSimplest' Equalizing dimension 5 using method 'BalanceSimplest' Equalizing dimension 6 using method 'BalanceSimplest' Equalizing dimension 7 using method 'BalanceSimplest' Equalizing dimension 8 using method 'BalanceSimplest' Equalizing dimension 9 using method 'BalanceSimplest' Equalizing dimension 10 using method 'BalanceSimplest' Equalizing dimension 11 using method 'BalanceSimplest' Equalizing dimension 12 using method 'BalanceSimplest' Equalizing dimension 13 using method 'BalanceSimplest' Equalizing dimension 14 using method 'BalanceSimplest' Equalizing dimension 15 using method 'BalanceSimplest' Equalizing dimension 16 using method 'BalanceSimplest' Equalizing dimension 17 using method 'BalanceSimplest' Equalizing dimension 18 using method 'BalanceSimplest' Equalizing dimension 19 using method 'BalanceSimplest' Equalizing dimension 20 using method 'BalanceSimplest' Equalizing dimension 21 using method 'BalanceSimplest' Equalizing dimension 22 using method 'BalanceSimplest' Equalizing dimension 23 using method 'BalanceSimplest' Equalizing dimension 24 using method 'BalanceSimplest' Equalizing dimension 25 using method 'BalanceSimplest' Equalizing dimension 26 using method 'BalanceSimplest' Equalizing dimension 27 using method 'BalanceSimplest' Equalizing dimension 28 using method 'BalanceSimplest' Equalizing dimension 29 using method 'BalanceSimplest' Logging changes to AnnData.uns['equalize_image_log'] Histogram equalization completed.
Out[16]:
AnnData object with n_obs × n_vars = 41529 × 17733
obs: 'barcode', 'x', 'y', 'n_genes_by_counts', 'log1p_n_genes_by_counts', 'total_counts', 'log1p_total_counts', 'pct_counts_in_top_50_genes', 'pct_counts_in_top_100_genes', 'pct_counts_in_top_200_genes', 'pct_counts_in_top_500_genes', 'total_counts_MT', 'log1p_total_counts_MT', 'pct_counts_MT', 'n_counts', 'leiden', 'cluster'
var: 'MT', 'n_cells_by_counts', 'mean_counts', 'log1p_mean_counts', 'pct_dropout_by_counts', 'total_counts', 'log1p_total_counts', 'n_cells', 'highly_variable', 'highly_variable_rank', 'means', 'variances', 'variances_norm'
uns: 'cluster_colors', 'hvg', 'leiden', 'leiden_colors', 'neighbors', 'pca', 'spatial_neighbors', 'umap', 'moranI', 'tiles', 'tiles_generated', 'embedding_method', 'tensor_resolution', 'na_filled_images_dict', 'smoothed_images_dict', 'equalize_image_log'
obsm: 'X_pca', 'X_umap', 'deconvolution_results', 'spatial', 'X_embedding', 'X_embedding_smooth', 'X_embedding_equalize'
layers: 'log_norm'
obsp: 'connectivities', 'distances', 'spatial_connectivities', 'spatial_distances'
In [17]:
SPIX.pl.image_plot(
adata,
dimensions=[0, 1, 2],
embedding='X_embedding_equalize',
figsize=(10, 10), # Adjust figure size here
scaling_factor=10, # Adjust point size here
origin=True
)
Parameter Selection¶
In [18]:
results_df = SPIX.op.parameter_selection(
adata,
original_moranI,
n_jobs=32
)
[Parallel(n_jobs=32)]: Using backend LokyBackend with 32 concurrent workers. /home/Data_Drive_8TB/chs1151/.conda/envs/V_t/lib/python3.10/site-packages/joblib/externals/loky/process_executor.py:752: UserWarning: A worker stopped while some jobs were given to the executor. This can be caused by a too short worker timeout or by a memory leak. warnings.warn( [Parallel(n_jobs=32)]: Done 8 tasks | elapsed: 43.5s [Parallel(n_jobs=32)]: Done 21 tasks | elapsed: 55.2s [Parallel(n_jobs=32)]: Done 34 tasks | elapsed: 1.1min [Parallel(n_jobs=32)]: Done 49 tasks | elapsed: 1.4min [Parallel(n_jobs=32)]: Done 64 tasks | elapsed: 1.7min [Parallel(n_jobs=32)]: Done 81 tasks | elapsed: 2.1min [Parallel(n_jobs=32)]: Done 96 out of 144 | elapsed: 2.2min remaining: 1.1min [Parallel(n_jobs=32)]: Done 111 out of 144 | elapsed: 2.4min remaining: 43.1s [Parallel(n_jobs=32)]: Done 126 out of 144 | elapsed: 2.6min remaining: 21.9s [Parallel(n_jobs=32)]: Done 141 out of 144 | elapsed: 2.7min remaining: 3.5s [Parallel(n_jobs=32)]: Done 144 out of 144 | elapsed: 2.8min finished
Segment Image¶
In [19]:
SPIX.sp.segment_image(
adata,
dimensions=list(range(30)),
embedding='X_embedding_equalize',
method='leiden_slic',
resolution=100,
origin=True,
compactness=10,
verbose=True
)
Starting image segmentation using method 'leiden_slic'... Image segmentation completed.
In [20]:
SPIX.pl.image_plot(
adata,
dimensions=[0, 1, 2],
embedding='X_embedding_segment',
figsize=(10, 10), # Adjust figure size here
scaling_factor=10, # Adjust point size here
origin=True,
boundary_linewidth=1,
brighten_factor=1.8,
boundary_style='solid', # 'solid', 'dashed', 'dotted'
# fixed_boundary_color='Black',
fill_boundaries=True,
fill_color='black',
fill_alpha=0.8,
plot_boundaries=True,
alpha=0.9
)
Make minibulk spots¶
In [21]:
new_adata, superpixel_moranI = SPIX.an.perform_pseudo_bulk_analysis(
adata,
segment_key='Segment',
min_cells=1,
normalize_total=False, # already normalized data
log_transform=False, # already normalized data
moranI_threshold=0.1,
mode="moran",
neighbors_kwargs={},
autocorr_kwargs={},
aggregate_expression=True,
add_bulk_layer=True,
highly_variable=True,
perform_pca=True,
neighbors_params={'n_neighbors': 15}
)
Starting Pseudo-Bulk Aggregation... Spatial coordinate aggregation complete. Aggregated into 1280 segments. Aggregating expression data... Expression data aggregation complete. New AnnData object creation complete. Performing optional expression data aggregation...
/home/Data_Drive_8TB/chs1151/.conda/envs/V_t/lib/python3.10/site-packages/anndata/_core/anndata.py:822: UserWarning:
AnnData expects .obs.index to contain strings, but got values like:
[0, 1, 2, 3, 4]
Inferred to be: categorical
names = self._prep_dim_index(names, "obs")
/home/Data_Drive_8TB/chs1151/.conda/envs/V_t/lib/python3.10/site-packages/anndata/_core/aligned_df.py:68: ImplicitModificationWarning: Transforming to str index.
warnings.warn("Transforming to str index.", ImplicitModificationWarning)
Expression data aggregation and merging complete. 'bulked' layer addition complete. Starting preprocessing... Gene filtering complete: Retained genes present in at least 1 segments. Spatial neighbors computation complete. Moran's I calculation complete. Number of genes with Moran's I >= 0.1: 2769 Highly Variable Genes calculation complete. PCA complete. Neighbors computation complete. Pseudo-Bulk analysis complete.
In [22]:
adata.layers['bulked'].toarray()
Out[22]:
array([[0. , 0.00632986, 0.00046213, ..., 0. , 0.00091608,
0. ],
[0. , 0.04362199, 0. , ..., 0. , 0.00127914,
0. ],
[0.00095916, 0.00764041, 0.01655191, ..., 0. , 0.01600238,
0. ],
...,
[0. , 0.02265343, 0.00669236, ..., 0. , 0. ,
0. ],
[0. , 0.01173735, 0.00892541, ..., 0. , 0.00897125,
0. ],
[0. , 0. , 0. , ..., 0. , 0. ,
0. ]], dtype=float32)
Vendiagram¶
In [23]:
import numpy as np
import matplotlib.pyplot as plt
from matplotlib_venn import venn3
from matplotlib_venn import venn2
In [24]:
set_adata = set(original_moranI.index)
set_new_adata2 = set(superpixel_moranI.index)
In [25]:
plt.figure(figsize=(8, 8))
venn = venn2([set_adata,set_new_adata2],
('Original', 'SuperPiexl'))
plt.title('Venn Diagram of Indices with Moran I > 0.1')
plt.show()
In [26]:
superpixel_unique = superpixel_moranI[superpixel_moranI.index.isin(np.setdiff1d(superpixel_moranI.index,original_moranI.index))]
In [27]:
superpixel_unique
Out[27]:
| I | pval_norm | var_norm | pval_norm_fdr_bh | |
|---|---|---|---|---|
| Slc5a7 | 0.680680 | 0.000000e+00 | 0.000241 | 0.000000e+00 |
| Amotl1 | 0.675773 | 0.000000e+00 | 0.000241 | 0.000000e+00 |
| Cldn2 | 0.624873 | 0.000000e+00 | 0.000241 | 0.000000e+00 |
| Prr32 | 0.615508 | 0.000000e+00 | 0.000241 | 0.000000e+00 |
| Zic4 | 0.607894 | 0.000000e+00 | 0.000241 | 0.000000e+00 |
| ... | ... | ... | ... | ... |
| Tdo2 | 0.100258 | 3.822775e-11 | 0.000241 | 2.451692e-10 |
| Rtf1 | 0.100130 | 4.037604e-11 | 0.000241 | 2.588533e-10 |
| Acyp2 | 0.100100 | 4.091094e-11 | 0.000241 | 2.621878e-10 |
| Olfm2 | 0.100063 | 4.156042e-11 | 0.000241 | 2.662540e-10 |
| Kif13b | 0.100009 | 4.253098e-11 | 0.000241 | 2.723734e-10 |
2567 rows × 4 columns
In [28]:
original_unique = original_moranI[original_moranI.index.isin(np.setdiff1d(original_moranI.index,superpixel_moranI.index))]
In [29]:
original_unique
Out[29]:
| I | pval_norm | var_norm | pval_norm_fdr_bh | |
|---|---|---|---|---|
| Acta2 | 0.246645 | 0.0 | 0.000007 | 0.0 |
| Cnr1 | 0.216980 | 0.0 | 0.000007 | 0.0 |
| Gad2 | 0.143751 | 0.0 | 0.000007 | 0.0 |
| Slc17a8 | 0.138658 | 0.0 | 0.000007 | 0.0 |
| Gnrh1 | 0.117854 | 0.0 | 0.000007 | 0.0 |
| Myh11 | 0.111274 | 0.0 | 0.000007 | 0.0 |
| Vtn | 0.110542 | 0.0 | 0.000007 | 0.0 |
| Tagln | 0.108735 | 0.0 | 0.000007 | 0.0 |
Ploting multicale genes¶
Superpixel Unique genes¶
In [30]:
import matplotlib.pyplot as plt
selected_genes = superpixel_unique[superpixel_unique['I'] > 0.5].head(10).index.tolist()
with plt.rc_context({'figure.figsize': [10, 10]}):
sc.pl.embedding(adata, basis='spatial', color=selected_genes, size=100,layer='bulked')
In [31]:
import matplotlib.pyplot as plt
selected_genes = superpixel_unique[superpixel_unique['I'] > 0.5].head(10).index.tolist()
with plt.rc_context({'figure.figsize': [10, 10]}):
sc.pl.embedding(adata, basis='spatial', color=selected_genes, size=100)
Original Unique gene¶
In [32]:
import matplotlib.pyplot as plt
selected_genes = original_unique.head(10).index.tolist()
with plt.rc_context({'figure.figsize': [10, 10]}):
sc.pl.embedding(adata, basis='spatial', color=selected_genes, size=100)
Ontology Analysis¶
In [33]:
Superpiexl_unique_list = superpixel_moranI[superpixel_moranI.index.isin(np.setdiff1d(superpixel_moranI.index,original_moranI.index))]
Origianl_unique = original_moranI[original_moranI.index.isin(np.setdiff1d(original_moranI.index,superpixel_moranI.index))]
Whole_intersection = superpixel_moranI[superpixel_moranI.index.isin(np.intersect1d(superpixel_moranI.index,original_moranI.index))]
In [35]:
gene_groups = {
'Superpixel_unique': Superpiexl_unique_list[Superpiexl_unique_list['I']>0.5].index,
'Original_unique' : Origianl_unique.index,
'Whole_intersection' : Whole_intersection[Whole_intersection['I']>0.5].index
}
databases = [
'GO_Biological_Process_2025',
# 'GO_Molecular_Function_2023',
# 'GO_Cellular_Component_2023',
# 'WikiPathways_2024_Mouse',
# 'Mouse_Gene_Atlas',
# 'HDSigDB_Mouse_2021',
# 'KEGG_2019_Mouse',
# 'KOMP2_Mouse_Phenotypes_2022'
]
# Perform analysis and generate clustermap
enrichment_results = SPIX.an.generate_enrichment_results(gene_groups, databases, verbose=False)
selected_database='GO_Biological_Process_2025'
p_value_threshold = 0.05
heatmap_df = SPIX.an.subset_enrichment_results(
enrichment_results,
selected_database=selected_database,
significance_threshold=p_value_threshold,
verbose=False
)
In [38]:
import pandas as pd
In [39]:
# Select top 20 rows by PD_enriched (descending order)
top20_SP = heatmap_df.sort_values(by='Superpixel_unique', ascending=False).head(10)
top20_OR = heatmap_df.sort_values(by='Original_unique', ascending=False).head(10)
# Select top 20 rows by CON_enriched (descending order)
top20_IN = heatmap_df.sort_values(by='Whole_intersection', ascending=False).head(10)
# (Optional) Combine both sets, removing duplicates if a Term appears in both
heatmap_df = pd.concat([top20_SP, top20_OR,top20_IN]).drop_duplicates()
In [45]:
clustermap = SPIX.an.create_enrichment_clustermap(
heatmap_df=heatmap_df,
selected_database=selected_database,
# term_pattern='neuro', # Regex pattern to filter terms
p_value_threshold=p_value_threshold,
cmap="Reds",
figsize=(14, 12),
metric="euclidean",
method="average",
add_annotations=True,
verbose=True
)
2025-04-09 03:53:46,049 - INFO - Starting clustermap generation. 2025-04-09 03:53:46,050 - INFO - Applying p-value threshold: 1.3010299956639813 2025-04-09 03:53:46,051 - DEBUG - Number of terms after p-value filtering: 25 2025-04-09 03:53:46,051 - DEBUG - Data transformation complete. 2025-04-09 03:53:46,052 - INFO - Generating clustermap. 2025-04-09 03:53:46,272 - INFO - Adding stars for significant p-values. 2025-04-09 03:53:46,282 - INFO - Clustermap generation complete.
Territory formation with minibulk spots¶
In [47]:
sc.tl.leiden(new_adata, flavor="igraph", n_iterations=2, resolution=1,key_added='spix_leiden')
new_adata.obs['spix_leiden'].nunique()
# tiles_equal
with plt.rc_context({'figure.figsize': [10 ,10]}):
sc.pl.embedding(new_adata,basis='spatial',color='spix_leiden',size=300,palette=sc.pl.palettes.default_102)
Transfer Territories to entire spots and compare with nonspatial leiden clustering¶
In [48]:
new_adata.obs.index = new_adata.obs.index.astype('int64')
adata.obs['spix_leiden'] = adata.obs['Segment'].map(new_adata.obs['spix_leiden'])
new_adata.obs.index = new_adata.obs.index.astype('str')
In [49]:
with plt.rc_context({'figure.figsize': [10 ,10]}):
sc.pl.embedding(adata,basis='spatial',color=['leiden','spix_leiden','cluster'],size=50,palette=sc.pl.palettes.default_102)
Experimental :: Territory formation with two time supepixels¶
In [50]:
new_adata = SPIX.tm.generate_embeddings(
new_adata,
dim_reduction='PCA',
normalization='none', # already normalized data
dimensions=30,
nfeatures=2000,
n_jobs=16,
filter_grid=1,
filter_threshold=0.98,
tensor_resolution=1,
chunksize=3000,
verbose=True
)
2025-04-09 03:56:37,018 - INFO - Starting generate_embeddings... 2025-04-09 03:56:37,019 - INFO - Tiles not found. Generating tiles... 2025-04-09 03:56:37,020 - INFO - Starting generate_tiles... 2025-04-09 03:56:37,021 - INFO - Original coordinates: (1280, 2) 2025-04-09 03:56:37,021 - INFO - Performing Voronoi tessellation... 2025-04-09 03:56:37,030 - INFO - Voronoi tessellation completed. 2025-04-09 03:56:37,030 - INFO - Filtering tiles... Calculating Voronoi region areas: 100%|██████████| 1280/1280 [00:00<00:00, 16928.78it/s] Filtering tiles by area: 100%|██████████| 1246/1246 [00:00<00:00, 2207901.47it/s] 2025-04-09 03:56:37,111 - INFO - Filtered regions: 1221, Filtered coordinates: (1221, 2) 2025-04-09 03:56:37,111 - INFO - Rasterising tiles... Rasterising tiles: 100%|██████████| 1221/1221 [00:07<00:00, 156.54it/s] 2025-04-09 03:56:51,562 - INFO - Rasterisation completed. Number of tiles: 17728332 2025-04-09 03:56:51,563 - INFO - Tiles have been stored in adata.uns['tiles']. 2025-04-09 03:56:52,453 - INFO - adata has been subset from 1280 to 1221 observations based on filtered tiles. 2025-04-09 03:56:52,454 - INFO - generate_tiles completed. 2025-04-09 03:56:52,455 - INFO - Processing counts... 2025-04-09 03:56:52,456 - INFO - Processing counts with method: none 2025-04-09 03:56:52,625 - INFO - Counts processing completed. 2025-04-09 03:56:52,632 - INFO - Embedding latent space... 2025-04-09 03:56:52,633 - INFO - Embedding latent space using PCA... 2025-04-09 03:56:52,986 - INFO - Latent space embedding completed. 2025-04-09 03:56:52,989 - INFO - generate_embeddings completed.
In [51]:
SPIX.pl.image_plot(
new_adata,
dimensions=[0, 1, 2],
embedding='X_embedding',
figsize=(10, 10), # Adjust figure size here
scaling_factor=50, # Adjust point size here
origin=True
)
In [52]:
SPIX.pl.image_plot(
new_adata,
dimensions=[0, 1, 2],
embedding='X_embedding',
figsize=(10, 10), # Adjust figure size here
scaling_factor=0.1, # Adjust point size here
origin=False
)
In [53]:
SPIX.ip.smooth_image(
new_adata,
dimensions = list(range(30)),
sigma=20,
n_jobs=30,
multi_method='loky'
)
2025-04-09 03:57:28,392 - INFO - Starting smooth_image... 2025-04-09 03:57:28,394 - INFO - Using embedding 'X_embedding' with shape (1221, 30). 2025-04-09 03:57:28,659 - INFO - Shifting coordinates by (-364, -125) to start from 0. 2025-04-09 03:57:29,194 - INFO - Image size: width=6877, height=6116 2025-04-09 03:57:29,195 - INFO - Starting parallel processing of dimensions... Filling NaNs: 0%| | 0/30 [00:00<?, ?it/s]
0%| | 0/30 [00:00<?, ?it/s]
2025-04-09 03:57:51,946 - INFO - Filling NaNs for dimension 0... 2025-04-09 03:57:52,799 - INFO - Filling NaNs for dimension 1... 2025-04-09 03:57:53,391 - INFO - Filling NaNs for dimension 2... 2025-04-09 03:57:54,406 - INFO - Filling NaNs for dimension 3... 2025-04-09 03:57:54,875 - INFO - Filling NaNs for dimension 4... 2025-04-09 03:57:55,864 - INFO - Filling NaNs for dimension 5... 2025-04-09 03:57:56,655 - INFO - Filling NaNs for dimension 6... 2025-04-09 03:57:57,682 - INFO - Filling NaNs for dimension 7... 2025-04-09 03:57:57,827 - INFO - Filling NaNs for dimension 8... 2025-04-09 03:57:58,936 - INFO - Filling NaNs for dimension 9... 2025-04-09 03:58:00,056 - INFO - Filling NaNs for dimension 10... 2025-04-09 03:58:00,568 - INFO - Filling NaNs for dimension 11... 2025-04-09 03:58:01,463 - INFO - Filling NaNs for dimension 12... 2025-04-09 03:58:01,497 - INFO - Filling NaNs for dimension 13... 2025-04-09 03:58:02,695 - INFO - Filling NaNs for dimension 14... 2025-04-09 03:58:03,079 - INFO - Filling NaNs for dimension 15... 2025-04-09 03:58:03,923 - INFO - Filling NaNs for dimension 16... 2025-04-09 03:58:05,046 - INFO - Filling NaNs for dimension 17... 2025-04-09 03:58:05,956 - INFO - Filling NaNs for dimension 18... 2025-04-09 03:58:06,441 - INFO - Filling NaNs for dimension 19... 2025-04-09 03:58:06,922 - INFO - Filling NaNs for dimension 20... 2025-04-09 03:58:07,742 - INFO - Filling NaNs for dimension 21... 2025-04-09 03:58:08,855 - INFO - Filling NaNs for dimension 22... 2025-04-09 03:58:09,381 - INFO - Filling NaNs for dimension 23... 2025-04-09 03:58:10,224 - INFO - Filling NaNs for dimension 24... 2025-04-09 03:58:10,543 - INFO - Filling NaNs for dimension 25... 2025-04-09 03:58:11,590 - INFO - Filling NaNs for dimension 26... 2025-04-09 03:58:12,146 - INFO - Filling NaNs for dimension 27... 2025-04-09 03:58:12,697 - INFO - Filling NaNs for dimension 28... 2025-04-09 03:58:13,581 - INFO - Filling NaNs for dimension 29... Filling NaNs: 0%| | 0/30 [01:00<?, ?it/s] Smoothing dimensions: 0%| | 0/30 [00:00<?, ?it/s]
0%| | 0/30 [00:00<?, ?it/s]
2025-04-09 03:58:30,916 - INFO - Smoothing for dimension 0... 2025-04-09 03:58:30,978 - INFO - Iteration 1/1 for dimension 0. 2025-04-09 03:58:31,911 - INFO - Smoothing for dimension 1... 2025-04-09 03:58:31,983 - INFO - Iteration 1/1 for dimension 1. 2025-04-09 03:58:32,902 - INFO - Smoothing for dimension 2... 2025-04-09 03:58:32,965 - INFO - Iteration 1/1 for dimension 2. 2025-04-09 03:58:33,939 - INFO - Smoothing for dimension 3... 2025-04-09 03:58:34,076 - INFO - Iteration 1/1 for dimension 3. 2025-04-09 03:58:35,018 - INFO - Smoothing for dimension 4... 2025-04-09 03:58:35,074 - INFO - Iteration 1/1 for dimension 4. 2025-04-09 03:58:36,064 - INFO - Smoothing for dimension 5... 2025-04-09 03:58:36,138 - INFO - Iteration 1/1 for dimension 5. 2025-04-09 03:58:37,111 - INFO - Smoothing for dimension 6... 2025-04-09 03:58:37,194 - INFO - Iteration 1/1 for dimension 6. 2025-04-09 03:58:38,179 - INFO - Smoothing for dimension 7... 2025-04-09 03:58:38,234 - INFO - Iteration 1/1 for dimension 7. 2025-04-09 03:58:39,179 - INFO - Smoothing for dimension 8... 2025-04-09 03:58:39,251 - INFO - Iteration 1/1 for dimension 8. 2025-04-09 03:58:40,409 - INFO - Smoothing for dimension 9... 2025-04-09 03:58:40,485 - INFO - Iteration 1/1 for dimension 9. 2025-04-09 03:58:41,394 - INFO - Smoothing for dimension 10... 2025-04-09 03:58:41,532 - INFO - Iteration 1/1 for dimension 10. 2025-04-09 03:58:42,612 - INFO - Smoothing for dimension 11... 2025-04-09 03:58:42,693 - INFO - Iteration 1/1 for dimension 11. 2025-04-09 03:58:43,688 - INFO - Smoothing for dimension 12... 2025-04-09 03:58:43,744 - INFO - Iteration 1/1 for dimension 12. 2025-04-09 03:58:44,856 - INFO - Smoothing for dimension 13... 2025-04-09 03:58:44,932 - INFO - Iteration 1/1 for dimension 13. 2025-04-09 03:58:45,822 - INFO - Smoothing for dimension 14... 2025-04-09 03:58:45,939 - INFO - Iteration 1/1 for dimension 14. 2025-04-09 03:58:46,964 - INFO - Smoothing for dimension 15... 2025-04-09 03:58:47,019 - INFO - Iteration 1/1 for dimension 15. 2025-04-09 03:58:47,942 - INFO - Smoothing for dimension 16... 2025-04-09 03:58:48,002 - INFO - Iteration 1/1 for dimension 16. 2025-04-09 03:58:49,205 - INFO - Smoothing for dimension 17... 2025-04-09 03:58:49,325 - INFO - Iteration 1/1 for dimension 17. 2025-04-09 03:58:50,171 - INFO - Smoothing for dimension 18... 2025-04-09 03:58:50,253 - INFO - Iteration 1/1 for dimension 18. 2025-04-09 03:58:51,365 - INFO - Smoothing for dimension 19... 2025-04-09 03:58:51,456 - INFO - Iteration 1/1 for dimension 19. 2025-04-09 03:58:52,244 - INFO - Smoothing for dimension 20... 2025-04-09 03:58:52,300 - INFO - Iteration 1/1 for dimension 20. 2025-04-09 03:58:53,424 - INFO - Smoothing for dimension 21... 2025-04-09 03:58:53,480 - INFO - Iteration 1/1 for dimension 21. 2025-04-09 03:58:54,434 - INFO - Smoothing for dimension 22... 2025-04-09 03:58:54,493 - INFO - Iteration 1/1 for dimension 22. 2025-04-09 03:58:55,616 - INFO - Smoothing for dimension 23... 2025-04-09 03:58:55,676 - INFO - Iteration 1/1 for dimension 23. 2025-04-09 03:58:56,637 - INFO - Smoothing for dimension 24... 2025-04-09 03:58:56,717 - INFO - Iteration 1/1 for dimension 24. 2025-04-09 03:58:57,774 - INFO - Smoothing for dimension 25... 2025-04-09 03:58:57,832 - INFO - Iteration 1/1 for dimension 25. 2025-04-09 03:58:58,722 - INFO - Smoothing for dimension 26... 2025-04-09 03:58:58,777 - INFO - Iteration 1/1 for dimension 26. 2025-04-09 03:58:59,925 - INFO - Smoothing for dimension 27... 2025-04-09 03:59:00,005 - INFO - Iteration 1/1 for dimension 27. 2025-04-09 03:59:01,116 - INFO - Smoothing for dimension 28... 2025-04-09 03:59:01,172 - INFO - Iteration 1/1 for dimension 28. 2025-04-09 03:59:02,109 - INFO - Smoothing for dimension 29... 2025-04-09 03:59:02,168 - INFO - Iteration 1/1 for dimension 29. Smoothing dimensions: 0%| | 0/30 [00:42<?, ?it/s] 2025-04-09 03:59:11,532 - INFO - Applying Min-Max scaling to the smoothed embeddings. 2025-04-09 03:59:11,537 - INFO - Smoothed embeddings stored in adata.obsm['X_embedding_smooth']. 2025-04-09 03:59:11,538 - INFO - Smoothing completed and embeddings updated in AnnData object.
Out[53]:
AnnData object with n_obs × n_vars = 1221 × 17733
obs: 'spix_leiden'
var: 'n_cells', 'highly_variable', 'means', 'dispersions', 'dispersions_norm'
uns: 'spatial_neighbors', 'moranI', 'hvg', 'pca', 'neighbors', 'spix_leiden', 'spix_leiden_colors', 'tiles', 'tiles_generated', 'embedding_method', 'tensor_resolution', 'na_filled_images_dict', 'smoothed_images_dict'
obsm: 'spatial', 'X_pca', 'X_embedding', 'X_embedding_smooth'
varm: 'PCs'
layers: 'counts', 'log_norm'
obsp: 'spatial_connectivities', 'spatial_distances', 'distances', 'connectivities'
In [54]:
SPIX.pl.image_plot(
new_adata,
dimensions=[0, 1, 2],
embedding='X_embedding_smooth',
figsize=(10, 10), # Adjust figure size here
scaling_factor=80, # Adjust point size here
origin=True
)
In [55]:
SPIX.ip.equalize_image(
new_adata,
dimensions=list(range(30)),
embedding='X_embedding_smooth',
sleft=5,sright=5)
Starting equalization... Equalizing dimension 0 using method 'BalanceSimplest' Equalizing dimension 1 using method 'BalanceSimplest' Equalizing dimension 2 using method 'BalanceSimplest' Equalizing dimension 3 using method 'BalanceSimplest' Equalizing dimension 4 using method 'BalanceSimplest' Equalizing dimension 5 using method 'BalanceSimplest' Equalizing dimension 6 using method 'BalanceSimplest' Equalizing dimension 7 using method 'BalanceSimplest' Equalizing dimension 8 using method 'BalanceSimplest' Equalizing dimension 9 using method 'BalanceSimplest' Equalizing dimension 10 using method 'BalanceSimplest' Equalizing dimension 11 using method 'BalanceSimplest' Equalizing dimension 12 using method 'BalanceSimplest' Equalizing dimension 13 using method 'BalanceSimplest' Equalizing dimension 14 using method 'BalanceSimplest' Equalizing dimension 15 using method 'BalanceSimplest' Equalizing dimension 16 using method 'BalanceSimplest' Equalizing dimension 17 using method 'BalanceSimplest' Equalizing dimension 18 using method 'BalanceSimplest' Equalizing dimension 19 using method 'BalanceSimplest' Equalizing dimension 20 using method 'BalanceSimplest' Equalizing dimension 21 using method 'BalanceSimplest' Equalizing dimension 22 using method 'BalanceSimplest' Equalizing dimension 23 using method 'BalanceSimplest' Equalizing dimension 24 using method 'BalanceSimplest' Equalizing dimension 25 using method 'BalanceSimplest' Equalizing dimension 26 using method 'BalanceSimplest' Equalizing dimension 27 using method 'BalanceSimplest' Equalizing dimension 28 using method 'BalanceSimplest' Equalizing dimension 29 using method 'BalanceSimplest' Logging changes to AnnData.uns['equalize_image_log'] Histogram equalization completed.
Out[55]:
AnnData object with n_obs × n_vars = 1221 × 17733
obs: 'spix_leiden'
var: 'n_cells', 'highly_variable', 'means', 'dispersions', 'dispersions_norm'
uns: 'spatial_neighbors', 'moranI', 'hvg', 'pca', 'neighbors', 'spix_leiden', 'spix_leiden_colors', 'tiles', 'tiles_generated', 'embedding_method', 'tensor_resolution', 'na_filled_images_dict', 'smoothed_images_dict', 'equalize_image_log'
obsm: 'spatial', 'X_pca', 'X_embedding', 'X_embedding_smooth', 'X_embedding_equalize'
varm: 'PCs'
layers: 'counts', 'log_norm'
obsp: 'spatial_connectivities', 'spatial_distances', 'distances', 'connectivities'
In [56]:
SPIX.pl.image_plot(
new_adata,
dimensions=[0, 1, 2],
embedding='X_embedding_equalize',
figsize=(10, 10), # Adjust figure size here
scaling_factor=80, # Adjust point size here
origin=True
)
In [57]:
SPIX.sp.segment_image(
new_adata,
dimensions=list(range(30)),
embedding='X_embedding_equalize',
method='leiden_slic',
resolution=1,
origin=True,
compactness=0.1,
verbose=True
)
Starting image segmentation using method 'leiden_slic'... Image segmentation completed.
In [58]:
with plt.rc_context({'figure.figsize': [10 ,10]}):
sc.pl.embedding(new_adata,basis='spatial',color='Segment',size=300,palette=sc.pl.palettes.default_102)
In [ ]:
Transfer Territories to entrie spots and compare with others¶
In [59]:
new_adata.obs.index = new_adata.obs.index.astype('int64')
adata.obs['bulked_segment'] = adata.obs['Segment'].map(new_adata.obs['Segment'])
new_adata.obs.index = new_adata.obs.index.astype('str')
In [60]:
with plt.rc_context({'figure.figsize': [10 ,10]}):
sc.pl.embedding(adata,basis='spatial',color=['leiden','spix_leiden','bulked_segment','cluster'],size=30,palette=sc.pl.palettes.default_102)
In [ ]:
Compare DEGs¶
Supepixel leiden territories¶
In [146]:
sc.tl.rank_genes_groups(adata,groupby='spix_leiden',pts=True,method='wilcoxon')
In [147]:
sc.tl.filter_rank_genes_groups(adata,groupby='spix_leiden',min_fold_change=2,max_out_group_fraction=0.1,min_in_group_fraction=0.1)
In [148]:
sc.pl.rank_genes_groups_dotplot(adata,key='rank_genes_groups_filtered')
WARNING: No genes found for group 15 WARNING: Groups are not reordered because the `groupby` categories and the `var_group_labels` are different. categories: 0, 1, 2, etc. var_group_labels: 0, 1, 2, etc.
two time Supepixel territories¶
In [166]:
adata.obs['bulked_segment'] = adata.obs['bulked_segment'].astype(str)
In [167]:
sc.tl.rank_genes_groups(adata,groupby='bulked_segment',pts=True,method='wilcoxon')
... storing 'bulked_segment' as categorical
In [171]:
sc.tl.filter_rank_genes_groups(adata,groupby='bulked_segment',min_fold_change=2,max_out_group_fraction=0.1,min_in_group_fraction=0.1)
In [172]:
sc.tl.dendrogram(adata,groupby='bulked_segment')
In [173]:
sc.pl.rank_genes_groups_dotplot(adata,key='rank_genes_groups_filtered')
WARNING: No genes found for group 4 WARNING: No genes found for group 13 WARNING: No genes found for group nan WARNING: Groups are not reordered because the `groupby` categories and the `var_group_labels` are different. categories: 0, 1, 2, etc. var_group_labels: 0, 1, 2, etc.
Nonspatial leiden clusters¶
In [149]:
sc.tl.rank_genes_groups(adata,groupby='leiden',pts=True,method='wilcoxon')
In [150]:
sc.tl.filter_rank_genes_groups(adata,groupby='leiden',min_fold_change=2,max_out_group_fraction=0.1,min_in_group_fraction=0.1)
In [151]:
sc.pl.rank_genes_groups_dotplot(adata,key='rank_genes_groups_filtered')
WARNING: No genes found for group 1 WARNING: No genes found for group 2 WARNING: Groups are not reordered because the `groupby` categories and the `var_group_labels` are different. categories: 0, 1, 2, etc. var_group_labels: 0, 3, 4, etc.
Annotation DEGs¶
In [152]:
sc.tl.rank_genes_groups(adata,groupby='cluster',pts=True,method='wilcoxon')
In [153]:
sc.tl.filter_rank_genes_groups(adata,groupby='cluster',min_fold_change=2,max_out_group_fraction=0.1,min_in_group_fraction=0.1)
In [154]:
sc.pl.rank_genes_groups_dotplot(adata,key='rank_genes_groups_filtered')
WARNING: dendrogram data not found (using key=dendrogram_cluster). Running `sc.tl.dendrogram` with default parameters. For fine tuning it is recommended to run `sc.tl.dendrogram` independently.
In [46]:
adata
Out[46]:
AnnData object with n_obs × n_vars = 41529 × 17733
obs: 'barcode', 'x', 'y', 'n_genes_by_counts', 'log1p_n_genes_by_counts', 'total_counts', 'log1p_total_counts', 'pct_counts_in_top_50_genes', 'pct_counts_in_top_100_genes', 'pct_counts_in_top_200_genes', 'pct_counts_in_top_500_genes', 'total_counts_MT', 'log1p_total_counts_MT', 'pct_counts_MT', 'n_counts', 'leiden', 'cluster', 'Segment'
var: 'MT', 'n_cells_by_counts', 'mean_counts', 'log1p_mean_counts', 'pct_dropout_by_counts', 'total_counts', 'log1p_total_counts', 'n_cells', 'highly_variable', 'highly_variable_rank', 'means', 'variances', 'variances_norm'
uns: 'cluster_colors', 'hvg', 'leiden', 'leiden_colors', 'neighbors', 'pca', 'spatial_neighbors', 'umap', 'moranI', 'tiles', 'tiles_generated', 'embedding_method', 'tensor_resolution', 'na_filled_images_dict', 'smoothed_images_dict', 'equalize_image_log'
obsm: 'X_pca', 'X_umap', 'deconvolution_results', 'spatial', 'X_embedding', 'X_embedding_smooth', 'X_embedding_equalize', 'X_embedding_segment', 'X_embedding_scaled_for_segment'
layers: 'log_norm', 'bulked'
obsp: 'connectivities', 'distances', 'spatial_connectivities', 'spatial_distances'
In [ ]:
Ontology Analysis¶
In [33]:
Superpiexl_unique_list = superpixel_moranI[superpixel_moranI.index.isin(np.setdiff1d(superpixel_moranI.index,original_moranI.index))]
Origianl_unique = original_moranI[original_moranI.index.isin(np.setdiff1d(original_moranI.index,superpixel_moranI.index))]
Whole_intersection = superpixel_moranI[superpixel_moranI.index.isin(np.intersect1d(superpixel_moranI.index,original_moranI.index))]
In [35]:
gene_groups = {
'Superpixel_unique': Superpiexl_unique_list[Superpiexl_unique_list['I']>0.5].index,
'Original_unique' : Origianl_unique.index,
'Whole_intersection' : Whole_intersection[Whole_intersection['I']>0.5].index
}
databases = [
'GO_Biological_Process_2025',
# 'GO_Molecular_Function_2023',
# 'GO_Cellular_Component_2023',
# 'WikiPathways_2024_Mouse',
# 'Mouse_Gene_Atlas',
# 'HDSigDB_Mouse_2021',
# 'KEGG_2019_Mouse',
# 'KOMP2_Mouse_Phenotypes_2022'
]
# Perform analysis and generate clustermap
enrichment_results = SPIX.an.generate_enrichment_results(gene_groups, databases, verbose=False)
selected_database='GO_Biological_Process_2025'
p_value_threshold = 0.05
heatmap_df = SPIX.an.subset_enrichment_results(
enrichment_results,
selected_database=selected_database,
significance_threshold=p_value_threshold,
verbose=False
)
In [38]:
import pandas as pd
In [39]:
# Select top 20 rows by PD_enriched (descending order)
top20_SP = heatmap_df.sort_values(by='Superpixel_unique', ascending=False).head(10)
top20_OR = heatmap_df.sort_values(by='Original_unique', ascending=False).head(10)
# Select top 20 rows by CON_enriched (descending order)
top20_IN = heatmap_df.sort_values(by='Whole_intersection', ascending=False).head(10)
# (Optional) Combine both sets, removing duplicates if a Term appears in both
heatmap_df = pd.concat([top20_SP, top20_OR,top20_IN]).drop_duplicates()
In [45]:
clustermap = SPIX.an.create_enrichment_clustermap(
heatmap_df=heatmap_df,
selected_database=selected_database,
# term_pattern='neuro', # Regex pattern to filter terms
p_value_threshold=p_value_threshold,
cmap="Reds",
figsize=(14, 12),
metric="euclidean",
method="average",
add_annotations=True,
verbose=True
)
2025-04-09 03:53:46,049 - INFO - Starting clustermap generation. 2025-04-09 03:53:46,050 - INFO - Applying p-value threshold: 1.3010299956639813 2025-04-09 03:53:46,051 - DEBUG - Number of terms after p-value filtering: 25 2025-04-09 03:53:46,051 - DEBUG - Data transformation complete. 2025-04-09 03:53:46,052 - INFO - Generating clustermap. 2025-04-09 03:53:46,272 - INFO - Adding stars for significant p-values. 2025-04-09 03:53:46,282 - INFO - Clustermap generation complete.
In [ ]:
In [ ]:
In [ ]:
In [ ]:
In [ ]:
In [ ]: